#include "../lib/tin.h"
#include "iostream"
#include "fstream"
#include "iomanip"

int main(int argc, char const *argv[])
{
	// read dem grid
	std::vector<double> topo(10201);
	std::ifstream infile("data/topo");
	for (int i = 0; i < 10201; ++i)
	{
		infile >> topo[i];
	}
	infile.close();

	std::vector<double> err_records;
	std::vector<vertex2dc*> tin_vert;
	std::vector<triangle*> tin_ele;
	grd2tin(topo, 0, 1000, 0, 1000, 10, 10, tin_vert, tin_ele, 1.0, nullptr, &err_records);

	// Write a log file
	std::ofstream logfile("data/topo_TIN.log");
	logfile << "# Insertion Maxi-Error\n";
	for (int i = 0; i < err_records.size(); ++i)
	{
		logfile << i+1 << " " << err_records[i] << std::endl;
	}
	logfile.close();

	// Write a Gmsh's .msh file
	std::ofstream outfile("data/topo_TIN.msh");
	outfile << "$MeshFormat" << std::endl << "2.2 0 8" << std::endl << "$EndMeshFormat "<<std::endl;
	outfile << "$Nodes" << std::endl << tin_vert.size() << std::endl;
	for (int i = 0; i < tin_vert.size(); i++)
	{
		outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16) 
			<< tin_vert[i]->x << " " << tin_vert[i]->y << " " << tin_vert[i]->elev << std::endl;
	}
	outfile<<"$EndNodes"<<std::endl;
	outfile << "$Elements" << std::endl << tin_ele.size() <<std::endl;
	for (int i = 0; i < tin_ele.size(); i++)
	{
		outfile << i + 1 << " 2 0";
		for (int j = 0; j < 3; j++)
		{
			outfile << " " << tin_ele[i]->vert[j]->id + 1;
		}
		outfile << std::endl;
	}
	outfile << "$EndElements"<< std::endl;
	outfile<<"$NodeData"<<std::endl;
	outfile<<1<<std::endl
		<<"\"Topography (m)\"" <<std::endl
		<< 1 <<std::endl<< 0.0 <<std::endl
		<< 3 <<std::endl<< 0<<std::endl
		<< 1 <<std::endl<< tin_vert.size() <<std::endl;
	for (int i = 0; i < tin_vert.size(); i++)
	{
		outfile << tin_vert[i]->id + 1 << " " << std::setprecision(16) << tin_vert[i]->elev << std::endl;
	}
	outfile << "$EndNodeData" << std::endl;
	outfile.close();

	// write a neighbor file
	outfile.open("data/topo_TIN.neigh");
	outfile << tin_ele.size() << std::endl;
	for (int i = 0; i < tin_ele.size(); i++)
	{
		outfile << i + 1;
		for (int j = 0; j < 3; j++)
		{
			if (tin_ele[i]->neigh[j] != nullptr)
			{
				outfile << " " << tin_ele[i]->neigh[j]->id + 1;
			}
			else outfile << " -1";
		}
		outfile << std::endl;
	}
	outfile.close();

	// Destroy memories allocated by the dem2tin function
	for (int i = 0; i < tin_vert.size(); ++i)
	{
		delete tin_vert[i];
	}

	for (int i = 0; i < tin_ele.size(); ++i)
	{
		delete tin_ele[i];
	}
	return 0;
}